using System;
using System.Collections.Generic;
using JetBrains.Annotations;
using UnityEngine;
using Voodoo.Sauce.Common.Utils;
using Voodoo.Tune.Core;

namespace Voodoo.Sauce.Internal.VoodooTune
{
	internal static class DebugVTManager
	{
		internal delegate void OnDebugConfigurationChange();

		private const string TAG = "DebugVTManager";

		private static readonly List<ABTestState> DebuggerAbTestStates = new List<ABTestState>
		{
			ABTestState.draft,
			ABTestState.pending,
			ABTestState.published,
			ABTestState.terminating
		};

		private static VersionMetadata _version;

		private static IReadOnlyList<ABTest> _abTests;

		private static IReadOnlyList<Segment> _segments;

		private static IReadOnlyList<Sandbox> _sandboxes;

		internal static DebugVTConfiguration CurrentDebugConfiguration { get; private set; }

		[CanBeNull]
		internal static DebugVTConfiguration DraftDebugConfiguration { get; private set; }

		internal static bool IsDraftDebugConfiguration
		{
			get
			{
				if (DraftDebugConfiguration != null)
				{
					return !DraftDebugConfiguration.Equals(CurrentDebugConfiguration);
				}
				return false;
			}
		}

		internal static event OnDebugConfigurationChange OnDebugConfigurationChangeEvent;

		internal static void Initialize()
		{
			CurrentDebugConfiguration = DebugVTConfiguration.GetFromPlayerPrefs();
			DraftDebugConfiguration = null;
			OnDebugConfigurationChangeEvent += OnDebugConfigurationUpdate;
		}

		internal static bool HasDebugBehaviorApplied()
		{
			if (CurrentDebugConfiguration == null)
			{
				throw new NullReferenceException("DebugVTManager.Initialize() should be called before this.");
			}
			return !CurrentDebugConfiguration.IsDefaultConfiguration;
		}

		internal static void RemoveDebugDraftConfiguration()
		{
			DraftDebugConfiguration = null;
			DebugVTManager.OnDebugConfigurationChangeEvent?.Invoke();
		}

		private static void OnDebugConfigurationUpdate()
		{
			if (DraftDebugConfiguration != null)
			{
				DraftDebugConfiguration.PersistOnPlayerPrefs();
			}
			else
			{
				CurrentDebugConfiguration.PersistOnPlayerPrefs();
			}
		}

		internal static void SelectDebugSandbox(Sandbox sandbox)
		{
			if (DraftDebugConfiguration == null)
			{
				throw new NullReferenceException("Can't select/deselect a sandbox because no draft configuration has been created.");
			}
			DraftDebugConfiguration = new DebugVTConfiguration
			{
				SelectedSandbox = sandbox
			};
			DebugVTManager.OnDebugConfigurationChangeEvent?.Invoke();
		}

		public static bool AddCohort(Cohort cohort, ABTest abTest)
		{
			if (DraftDebugConfiguration == null)
			{
				throw new NullReferenceException("Can't select a cohort because no draft configuration has been created.");
			}
			if (DraftDebugConfiguration.SelectedCohorts.Contains(cohort))
			{
				return false;
			}
			DraftDebugConfiguration.SelectedSandbox = null;
			DraftDebugConfiguration.SelectedAbTests.Add(abTest);
			DraftDebugConfiguration.SelectedCohorts.Add(cohort);
			DraftDebugConfiguration.VersionId = _version.Id;
			DebugVTManager.OnDebugConfigurationChangeEvent?.Invoke();
			return true;
		}

		public static bool RemoveCohort(Cohort cohort, ABTest abTest)
		{
			if (DraftDebugConfiguration == null)
			{
				throw new NullReferenceException("Can't select a cohort because no draft configuration has been created.");
			}
			if (!DraftDebugConfiguration.SelectedCohorts.Contains(cohort))
			{
				return false;
			}
			DraftDebugConfiguration.SelectedSandbox = null;
			DraftDebugConfiguration.SelectedAbTests.Remove(abTest);
			DraftDebugConfiguration.SelectedCohorts.Remove(cohort);
			DebugVTManager.OnDebugConfigurationChangeEvent?.Invoke();
			return true;
		}

		public static void ClearCohorts()
		{
			if (DraftDebugConfiguration != null)
			{
				DraftDebugConfiguration.SelectedAbTests.Clear();
				DraftDebugConfiguration.SelectedCohorts.Clear();
				DebugVTManager.OnDebugConfigurationChangeEvent?.Invoke();
			}
		}

		public static void ClearSandboxes()
		{
			if (DraftDebugConfiguration != null)
			{
				DraftDebugConfiguration.SelectedSandbox = null;
				DebugVTManager.OnDebugConfigurationChangeEvent?.Invoke();
			}
		}

		public static bool AddDebugSegment(Segment segment)
		{
			if (DraftDebugConfiguration == null)
			{
				throw new NullReferenceException("Can't select a segment because no draft configuration has been created.");
			}
			if (segment == null || DraftDebugConfiguration.SelectedSegments.Contains(segment))
			{
				return false;
			}
			DraftDebugConfiguration.SelectedSandbox = null;
			DraftDebugConfiguration.SelectedSegments.Add(segment);
			DraftDebugConfiguration.VersionId = _version.Id;
			DebugVTManager.OnDebugConfigurationChangeEvent?.Invoke();
			return true;
		}

		public static bool RemoveDebugSegment(Segment segment)
		{
			if (DraftDebugConfiguration == null)
			{
				throw new NullReferenceException("Can't select a segment because no draft configuration has been created.");
			}
			if (segment == null || !DraftDebugConfiguration.SelectedSegments.Contains(segment))
			{
				return false;
			}
			DraftDebugConfiguration.SelectedSandbox = null;
			DraftDebugConfiguration.SelectedSegments.Remove(segment);
			DebugVTManager.OnDebugConfigurationChangeEvent?.Invoke();
			return true;
		}

		public static void ClearDebugSegments()
		{
			if (DraftDebugConfiguration != null)
			{
				DraftDebugConfiguration.SelectedSegments.Clear();
				DebugVTManager.OnDebugConfigurationChangeEvent?.Invoke();
			}
		}

		internal static async void LoadDebugConfigurations(Action onSuccess, Action<string> onError)
		{
			if (!PlatformUtils.UNITY_IOS && !PlatformUtils.UNITY_ANDROID && !PlatformUtils.UNITY_EDITOR)
			{
				throw new NotImplementedException("This method only works on an Android/iOS project.");
			}
			string error = null;
			try
			{
				VoodooTuneClient client = new VoodooTuneClient();
				VoodooLog.LogDebug(Module.VOODOO_TUNE, "DebugVTManager", "LoadDebugConfigurations API call for " + Application.identifier + " (" + VoodooTunePersistentData.SavedStatus.ToString() + ")");
				_version = await client.App.Version.Get(Application.identifier, VoodooTunePersistentData.SavedStatus.ToString());
				VoodooTunePersistentData.SavedAppId = _version.AppId;
				VoodooLog.LogDebug(Module.VOODOO_TUNE, "DebugVTManager", "LoadDebugConfigurations Version success");
				if (VoodooTunePersistentData.SavedAppId == null)
				{
					onError("The AppId returned by the service is null.");
					return;
				}
				try
				{
					_abTests = await client.App.Version.AbTest.GetAll(_version.AppId, _version.Id, DebuggerAbTestStates);
					_segments = await client.App.Version.Segment.GetAll(_version.AppId, _version.Id);
					_sandboxes = await client.App.Sandbox.GetAll(_version.AppId);
				}
				catch (Exception ex)
				{
					error = ex.Message;
				}
			}
			catch (Exception ex2)
			{
				error = ex2.Message;
			}
			if (!string.IsNullOrEmpty(error))
			{
				VoodooLog.LogError(Module.VOODOO_TUNE, "DebugVTManager", "LoadDebugConfigurations API error");
				onError?.Invoke(error);
			}
			else
			{
				VoodooLog.LogDebug(Module.VOODOO_TUNE, "DebugVTManager", "LoadDebugConfigurations API success");
				onSuccess?.Invoke();
			}
		}

		internal static IEnumerable<Sandbox> GetDebugSandboxes()
		{
			if (_sandboxes == null)
			{
				throw new NullReferenceException("A debug configuration should be loaded before calling this method.");
			}
			return _sandboxes;
		}

		internal static IEnumerable<ABTest> GetDebugAbTests()
		{
			if (_abTests == null)
			{
				throw new NullReferenceException("A debug configuration should be loaded before calling this method.");
			}
			return _abTests;
		}

		internal static IEnumerable<Segment> GetDebugSegments()
		{
			if (_segments == null)
			{
				throw new NullReferenceException("A debug configuration should be loaded before calling this method.");
			}
			return _segments;
		}

		internal static void NewDebugDraftConfiguration()
		{
			DraftDebugConfiguration = new DebugVTConfiguration();
			if (CurrentDebugConfiguration != null)
			{
				DraftDebugConfiguration.SelectedAbTests = new List<ABTest>(CurrentDebugConfiguration.SelectedAbTests);
				DraftDebugConfiguration.SelectedCohorts = new List<Cohort>(CurrentDebugConfiguration.SelectedCohorts);
				DraftDebugConfiguration.SelectedSegments = new List<Segment>(CurrentDebugConfiguration.SelectedSegments);
				DraftDebugConfiguration.SelectedSandbox = CurrentDebugConfiguration.SelectedSandbox;
				DraftDebugConfiguration.VersionId = CurrentDebugConfiguration.VersionId;
			}
			DebugVTManager.OnDebugConfigurationChangeEvent?.Invoke();
		}

		internal static void ResetDebugDraftConfiguration()
		{
			DraftDebugConfiguration = new DebugVTConfiguration();
			DebugVTManager.OnDebugConfigurationChangeEvent?.Invoke();
		}
	}
}
